import { defineLoader } from 'vitepress'
import type { MetaCheckerOptions } from 'vue-component-meta'
import { createComponentMetaChecker } from 'vue-component-meta'
import fs from 'fs'
import path from 'path'

export default defineLoader({
  load() {
    console.log('生成 Api 数据中...')
    const checkerOptions: MetaCheckerOptions = {
      forceUseTs: true,
      schema: { ignore: ['MyIgnoredNestedProps'] },
      printer: { newLine: 1 },
      noDeclarations: true,
    }

    const checker = createComponentMetaChecker(
      // Write your tsconfig path
      path.resolve('tsconfig.json'),
      checkerOptions,
    )

    const componentData = {}
    fs.readdirSync('src').forEach((dir) => {
      if (!dir.startsWith('_') && dir !== 'icons') {
        const file =
          dir === 'modal'
            ? 'Modal.vue'
            : dir === 'toast'
              ? 'index.tsx'
              : 'index.vue'
        try {
          const meta = checker.getComponentMeta(
            path.resolve(`src/${dir}/${file}`),
          )
          // todo 目前 vue-component-meta 库无法提取 props 上的事件
          const props = meta.props
            .filter(({ global }) => !global)
            .map(({ name, description, type, default: defaultV }) => ({
              name,
              description,
              type,
              default: defaultV,
            }))
          let slots = []
          try {
            slots = meta.slots.map(({ name, description, type }) => ({
              name,
              description,
              type,
            }))
          } catch (error) {}

          let events = []
          try {
            events = meta.events.map(({ name, type }) => ({
              name,
              type: `(${type.slice(1, -1)}) => void`,
            }))
          } catch (error) {}

          componentData[dir] = {
            props,
            events,
            slots,
            // exposed: meta.exposed,
          }
        } catch (error) {}
      }
    })
    console.log('Api 数据生成完成')
    return componentData
  },
})

export interface Data {
  // data type
}

declare const data: Data
export { data }
